import base64
import json
import pickle
import re

from django import http
from django.contrib.auth import login, authenticate, logout
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.carts.utils import move_cart_cookie_to_redis
from apps.goods.models import SKU
from apps.users import constants
from apps.users.utils import generate_verify_email_url, check_verify_email_token
from apps.verifications.utils import check_access_token
from meiduo_mall import settings
from utils.response_code import RETCODE
from utils.views import LoginRequiredJSONMixin
from .models import User, Address
import logging
logger = logging.getLogger('django')

'''
一、前端分析
从客户端得到数据
二、后端分析
1. 获取前端的用户名, 密码, 手机号
2. 进行数据验证
    2.1 用户名的5-20个字符, 不重复
    2.2 密码的8-20位字符
    2.3 密码的二次验证
    2.4 手机号的11位数字, 不重复
3. 存入数据库, 实现注册功能
4. 返回注册成功
三、确定路由
使用POST请求 	 地址为/register/
'''

# 注册
class RegisterView(View):
    def get(self, request):
        # return HttpResponse('OK')
        return render(request, 'register.html')

    def post(self, request):
        # 1.获取前端的用户名, 密码,二次确认密码 手机号, 勾选用户协议
        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        mobile = request.POST.get('mobile')
        allow = request.POST.get('allow')
        # 获取前端的短信验证码, 与后端生成的验证码进行对比
        sms_code_client = request.POST.get('sms_code')

        # 2. 进行数据验证
        # 判断用户是否填写全部参数 all里边是个列表
        if not all([username, password, password2, mobile, allow]):
            return http.HttpResponseBadRequest('缺少必要参数')
            #     2.1 用户名的5-20个字符, 不重复
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseBadRequest('请输入5-20个字符的用户名')
            #     2.2 密码的8-20位字符
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseBadRequest('请输入8-20位的密码')
            #     2.3 密码的二次验证
        if password != password2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')
            #     2.4 手机号的11位数字, 不重复
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('请输入正确的手机号码')
            #     2.5 是否勾选用户协议
        if allow != 'on':
            return http.HttpResponseBadRequest('请勾选用户协议')

        # 保存注册数据前需要对比用户输入的验证码和后台生成的验证码
        redis_conn = get_redis_connection('code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        # 如果后台没有验证码, 返回错误信息
        if sms_code_server is None:
            return render(request, 'register.html', {'sms_code_errmsg': '无效的短信验证码'})
        # 如果验证码不相等, 返回错误信息
        if sms_code_client != sms_code_server.decode():
            return (request, 'register.html', {'sms_code_errmsg': '输入的短信验证码有误'})

        # 3. 把用户名, 密码, 手机号存入数据库, 实现注册功能
        from django.db import DatabaseError

        try:
            # create_user可以对密码进行加密处理
            user = User.objects.create_user(
                username=username,
                password=password,
                mobile=mobile
            )
        except DatabaseError:
            return render(request, 'register.html', {'register_errmsg': '注册失败'})

        '''
        注册成功, 自动登录
        保存登录状态, cookie和session(敏感数据)
        '''
        login(request, user)

        # 4. 注册成功返回主页
        # path = reverse('namespace:index')
        path = reverse('contents:index')
        response = redirect(path)

        # 注册时用户名写入到cookie，有效期15天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        return response
        # return http.HttpResponse('注册成功, 重定向到首页')


'''
用户名重复业务实现
前端得到用户名数据

后端去获取前端数据在数据库中查询是否有相同的用户名
如果有,返回数量1, 如果没有, 返回数量0
'''


# 重新定义一个类, 专门用来判断用户名是否相同
class UsernameCountView(View):
    def get(self, request, username):
        # 1. 获取用户名
        # 2. 查询用户名是否重复, 重复则count返回 1
        # 3. 返回json数据, 包含用户名重复数量 1
        count = User.objects.filter(username=username).count()
        return http.JsonResponse({'count': count})


# 重定义一个类, 处理手机号重复
class MobileCountView(View):
    def get(self, request, mobile):
        # 1. 从前端获取mobile数据
        # 2. 在数据库中查询手机号  count=1 重复了 =0 没重复
        # 3. 返回json数据到前端, 使用ajax告知用户手机号重复
        count = User.objects.filter(mobile=mobile).count()
        return http.JsonResponse({'count': count})


'''
前端分析
获取用户输入的用户名和密码

后端分析
1. 获取前端得到的用户名和密码
2. 对用户名和密码进行正则比对, 不符合规定的数据直接返回错误
3. 对比数据库中的用户名
4. 对比数据库中的密码
5. 设置登录状态(session)
请求方式和路径
POST    login/
'''


# 重新定义一个类, 处理用户帐号登录
class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        # 1.获取前端得到的用户名和密码, 是否勾选记住登录
        username = request.POST.get('username')
        password = request.POST.get('password')
        remembered = request.POST.get('remembered')
        next = request.GET.get('next')

        # 判断数据是否齐全
        if not all([username, password]):
            return http.HttpResponseBadRequest('参数不全')

        # 2.对用户名和密码进行正则比对, 不符合规定的数据直接返回错误
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseBadRequest('请输入正确的用户名或手机号')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseBadRequest('密码最少8位，最长20位')

        # 3.对比数据库中的用户名和密码
        # 使用django自带的用户认证
        user = authenticate(request, username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})

        # 4. 设置登录状态(session)
        login(request, user)
        # 如果用户勾选记住密码, 需要设置session有效期为默认两周,否则浏览器会话结束后过期
        if remembered != 'on':
            # 没有记住用户：浏览器会话结束就过期
            request.session.set_expiry(0)
        else:
            # 记住用户：None表示两周后过期
            request.session.set_expiry(None)

        # 如果next中有值,就跳转到next中的值的页面
        if next:
            response = redirect(next)
        # 如果没有,重定向到首页  响应登录结果
        else:
            response = redirect(reverse('contents:index'))

        # 注册时用户名写入到cookie中, 有效期为15天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        # 登录时合并购物车
        move_cart_cookie_to_redis(request, response, user)

        return response

'''
帐号退出是使用logout方法
后端逻辑
清理登录时候保存的session信息
由于登陆时用户名存储到cookie中, 所以退出时也需要清理cookie中的用户名
重定向到登录页

路由方式和路径
GET     Logout/
'''

# 重新定义一个类, 处理用户帐号退出
class LogoutView(View):
    def get(self, request):
        # 清理session
        logout(request)
        # 推出登录, 重定向到登录页
        response = redirect(reverse('users:login'))
        # 退出时清除cookie中的username
        response.delete_cookie('username')

        return response


# 重新定义一个类, 处理用户中心页面的展示
from django.contrib.auth.mixins import LoginRequiredMixin
class UserInfoView(LoginRequiredMixin, View):
    # 搭配LoginRequiredMixin表示当用户未通过登录验证时，将用户重定向到登录页面。
    login_url = '/login/'
    def get(self, request):

        context = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,
            'email_active':request.user.email_active,
        }

        return render(request, 'user_center_info.html', context=context)



'''
保存验证邮箱的后端逻辑
1. 获取更新哪个用户的信息并验证用户输入的邮箱格式是否正确
2. 用户点击保存邮箱就把邮箱保存起来, 并设置邮箱状态未认证
3. 后端发送验证邮件
4. 用户点击链接, 验证成功修改邮箱登录状态

请求方式和路径
PUT           emails/
'''
# 重新定义一个类, 处理用户邮箱保存和验证邮件发送业务
class EmailView(LoginRequiredJSONMixin, View):
    def put(self, request):
    # 1. 验证用户输入的邮箱格式是否正确
        # 接受body中的数据
        body = request.body
        # body中的数据是bytes类型需要字符串
        json_str = body.decode()
        # 将字符串转换成字典
        json_dict = json.loads(json_str)
        # 从字典中获取用户输入的邮箱地址
        email = json_dict.get('email')

        # 验证邮箱是否正确
        if not email:
            return http.HttpResponseBadRequest('邮箱未输入')
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.HttpResponseBadRequest('邮箱格式有误')

        # 2. 用户点击保存邮箱就把邮箱保存起来
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '添加邮箱失败'})

    # 3. 后端发送验证邮件
        # 异步发送验证邮件
        from celery_tasks.email.tasks import send_verify_email
        # 使用邮箱验证链接
        verify_url = generate_verify_email_url(request.user)
        send_verify_email.delay(email, verify_url)

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加邮箱成功'})


# 重新定义一个类, 处理用户验证邮箱的业务
class VerifyEmailView(View):
    # 4. 用户点击链接, 验证成功修改邮箱登录状态
    def get(self, requset):
        # 接收token
        token = requset.GET.get('token')
        # 验证token是否过期或为空
        if not token:
            return http.HttpResponseBadRequest('缺少token')
        # 对token解密出用户信息
        user = check_verify_email_token(token)
        if not user:
            return http.HttpResponseBadRequest('无效的token')
        # 用户信息验证通过后, 修改email_active为Ture
        try:
            user.email_active=True
            user.save()
        except Exception as e:
            logger.error(e)
            return http.HttpResponseBadRequest('激活邮箱失败')

        # 重定向到用户中心
        return redirect(reverse('users:center'))


'''
展示收货地址就是根据条件查询用户以添加过的收货地址
前端逻辑
    展示后端查询的数据

后端逻辑
    1. 根据条件查询数据
    2. 获取数据
    3. 返回响应
'''
# 重新定义一个类, 展示收货地址html页面
class AddressView(LoginRequiredMixin, View):
    def get(self, request):
        # 1. 根据条件查询数据
        # 获取用户的收货地址列表
        login_user= request.user
        addresses = Address.objects.filter(user=login_user, is_deleted=False)

        # 2. 获取数据
        address_dict_list = []
        for address in addresses:
            address_dict={
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "province_id": address.province_id,
                "city": address.city.name,
                "city_id": address.city_id,
                "district": address.district.name,
                "district_id": address.district_id,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            }
            address_dict_list.append(address_dict)

        # 3. 返回响应
        context = {
            'username':request.user.username,
            'default_address_id': login_user.default_address_id,
            'addresses': address_dict_list
        }
        return render(request, 'user_center_site.html', context)



'''
前端逻辑
    收集用户输入的信息

后端逻辑
    1. 接受前端收集的数据
    2. 验证数据
    3. 保存数据
    4. 返回响应

请求方式和路径
POST     addresses/create/
'''
# 定义一个类, 处理新增收货地址的业务
class CreateAddressView(LoginRequiredMixin, View):

    def post(self, request):
        # 判断收货地址上限, 最多20个
        # Address.objects.filter(user=request.user).count()
        count = request.user.addresses.count()
        if count >= constants.USER_ADDRESS_COUNTS_LIMIT:
            return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '超过地址数量上限'})

        # 1.接受前端收集的数据
        json_dict = json.loads(request.body.decode())
        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')

        # 2. 验证数据
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.HttpResponseBadRequest('缺少必传参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')

        # 3. 保存数据
        try:
            address = Address.objects.create(
                user=request.user,
                title=receiver,
                receiver=receiver,
                province_id=province_id,
                city_id=city_id,
                district_id=district_id,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email
            )
            # 设置默认地址
            if not request.user.default_address:
                request.user.default_address = address
                request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg':'新增地址失败'})
        # 4. 返回响应
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '新增地址成功', 'address':address_dict})


'''
前端逻辑
    获取用户输入的地址id和其他更新数据

后端逻辑
    1. 接收更新的地址id
    2. 接受更新的数据
    3. 验证更新数据
    4. 更新数据库内对应的数据
    5. 返回响应

请求方式和响应
PUT      addresses/(?P<address_id>\d+)
'''
# 定义一个类, 处理修改收货地址的业务
class UpdateAddressView(LoginRequiredJSONMixin, View):
    def put(self, request, address_id):
        # 1. 接收更新的地址id
        json_dict = json.loads(request.body.decode())
        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')

        # 2. 接受更新的数据
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.HttpResponseBadRequest('缺少必传参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')

        # 3. 验证更新数据
        # 4. 更新数据库内对应的数据
        try:
            address = Address.objects.filter(id=address_id).update(
                user=request.user,
                title=receiver,
                receiver=receiver,
                province_id=province_id,
                city_id=city_id,
                district_id=district_id,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email
            )
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '更新地址失败'})
        if address != 1:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '更新地址失败'})

        # 5. 返回响应
        # 构造响应数据
        address = Address.objects.get(id=address_id)
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '更新地址成功', 'address': address_dict})

    '''
    前端逻辑
        接受用户要删除对应的地址id

    后端逻辑
        1. 接收要删除的地址id
        2. 查询数据
        3. 删除数据
        4. 返回响应

    请求方式和路径
    DELETE   /addresses/(?P<address_id>\d+)/
    '''
    def delete(self, request, address_id):
        # 1. 接收要删除的地址id
        try:
            # 2. 查询数据
            address = Address.objects.get(id=address_id)
            # 3. 逻辑删除数据
            address.is_deleted = True
            address.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '删除地址失败'})
        # 4. 返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '删除地址成功'})


'''
前端逻辑
        接受用户要设置默认的地址id

后端逻辑
        1. 接收要设置默认的地址id
        2. 查询数据
        3. 更新default_address 字段
        4. 返回响应

请求方式和路径
PUT        addresses/(?P<address_id>\d+)/default/
'''
# 重新定义一个类, 处理设置默认地址的业务
class DefaultAddressView(LoginRequiredMixin, View):
    def put(self, request, address_id):
        # 1. 接收要设置默认的地址id
        try:
            address = Address.objects.get(id=address_id)
        # 2. 查询数据
        # 3. 更新default_address 字段
            request.user.default_address = address
            request.user.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '设置默认地址失败'})
        # 4. 返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '设置默认地址成功'})


'''
前端逻辑
        接受用户要设置标题的地址id

后端逻辑
        1. 接收要设置标题的地址id
        2. 查询数据
        3. 更新title字段
        4. 返回响应

请求方式和路径
PUT        addresses/(?P<address_id>\d+)/title/
'''
# 重新定义一个类, 处理修改地址标题的业务
class UpdateTitleAddressView(LoginRequiredMixin, View):
    def put(self, request, address_id):
        # 1. 接收要设置标题的地址id
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        try:
            # 2. 查询数据
            address = Address.objects.get(id=address_id)
            # 3. 更新title字段
            address.title = title
            address.save()
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '设置地址标题失败'})
        # 4. 返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '设置地址标题成功'})


'''
前端逻辑
        接受用户新密码数据

后端逻辑
        1. 接收用户新密码数据并验证
        2. 验证输入的原密码与数据库中是否一致
        3. 更新密码
        4. 退出登录
        5. 重定向到登录页面

请求方式和路径
GET (展示修改密码页面)
POST       changepassword/
'''
# 重新定义一个类, 处理修改密码业务
class ChangePasswordView(LoginRequiredMixin, View):
    def get(self, request):
        # 展示修改密码页面
        return render(request, 'user_center_pass.html')

    def post(self, request):
        # 1. 接收用户新密码数据并验证
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        new_password2 = request.POST.get('new_password2')

        # 2. 验证输入的原密码与数据库中是否一致
        if not all([old_password, new_password, new_password2]):
            return http.HttpResponseForbidden('缺少必传参数')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return http.HttpResponseBadRequest('密码最少8位，最长20位')
        if new_password != new_password2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')

        # 验证旧密码是否正确
        if not request.user.check_password(old_password):
            return render(request, 'user_center_pass.html', {'origin_password_errmsg': '原始密码错误'})

        # 3. 更新密码
        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            logger.error(e)
            return render(request, 'user_center_pass.html', {'change_password_errmsg': '修改密码失败'})

        # 4. 退出登录
        logout(request)

        # 5. 重定向到登录页面
        response = redirect(reverse('users:login'))
        response.delete_cookie('username')

        return response


'''
前端逻辑
    获取登录用户浏览商品id

后端逻辑
    1. 接收商品id
    2. 验证数据
    3. 把数据写入redis
    4. 返回响应

请求方式和路径
POST         browse_histories/
'''
# 定义一个类, 处理保存和查询用户商品浏览记录的业务
class GoodsHistoryView(LoginRequiredJSONMixin, View):

    def post(self, request):
        # 1. 接收商品id
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')

        # 2. 验证数据
        try:
            SKU.objects.get(pk=sku_id)
        except SKU.DoesNotExist:
            return http.JsonResponse({'code': RETCODE.NODATAERR, 'errmsg':'此商品不存在'})

        # 3. 把数据写入redis
        # 3.1连接redis
        redis_conn = get_redis_connection('history')
        pl = redis_conn.pipeline()
        user_id = request.user.id

        # 3.2先去重
        # LREM key count value 根据参数 count 的值，移除列表中与参数 value 相等的元素。
        pl.lrem('histtory_%s' % user_id, 0 ,sku_id)
        # 3.3再添加
        pl.lpush('history_%s' % user_id, sku_id)
        # 3.4列表中只显示5条数据
        # LTRIM key start stop  对一个列表进行修剪
        pl.ltrim('history_%s' % user_id, 0, 4)
        # 执行管道
        pl.execute()

        # 4. 返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})


    def get(self, request):
        # 1. 获取redis中的浏览记录
        redis_conn = get_redis_connection('history')
        sku_ids = redis_conn.lrange('history_%s' % request.user.id, 0, -1)

        # 根据sku_id列表数据, 查询出商品sku信息
        skus = []
        for sku_id in sku_ids:
            sku = SKU.objects.get(pk=sku_id)
            skus.append({
                'id': sku.id,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price
            })
        # 返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'skus': skus})



'''
前端逻辑
    收集用户输入数据

后端逻辑
    1. 先获取用户输入的用户名,图片验证码并验证
    2. 然后获取用户手机号, 短信验证码并验证
    3. 再获取用户输入的新的密码并验证
    4. 根据用户id修改数据库中密码字段
    5. 返回响应
请求方式和路径
'''
# 展示忘记密码页面
class FindPwdView(View):
    def get(self, request):
        return render(request, 'find_password.html')

# 实现忘记密码找回功能
class ChangePwdView(View):
    def post(self, request, user_id):
        # 获取body中的数据
        data_dict = json.loads(request.body.decode())
        password = data_dict.get('password')
        password2 = data_dict.get('password2')
        access_token = data_dict.get('access_token')

        # 数据是否齐全
        if not all([password, password2, access_token]):
            return http.HttpResponseBadRequest('参数不全')

        # 密码是否符合规则
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.HttpResponseBadRequest('密码格式不对')
        # 两次输入密码是否一致
        if password != password2:
            return http.HttpResponseBadRequest('两次密码输入不一致')

        # 对token进行解码得到找回密码用户信息
        user_dict = check_access_token(access_token)
        # 对用户信息进行判断
        if user_dict is None:
            return http.HttpResponseBadRequest('没有用户信息')
        # 对用户id验证
        if int(user_id) != user_dict.get('user_id'):
            return http.HttpResponseBadRequest('用户信息不正确')

        # 更新密码字段
        try:
            user = User.objects.get(pk=user_id)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseBadRequest('用户信息不正确')
        # 写入新密码
        user.set_password(password)
        user.save()
        return render(request, 'login.html')
